/*
 * main.cc
 *
 *  Created on: 02.06.2010
 *      Author: werd
 */

#include "memory.h"
#include "util.h"
#include <iostream>
#include <cstdlib>
#include <iomanip>
#include <cstring>

//#include <time.h> // speed run check

#include <fstream>   // write to file


using std::cin;
using std::cout;

using std::ofstream;
using std::ifstream;
using std::max;
using std::setw;

const int MAX_STR_LEN = 10;
enum prop{
/*
n1[1-21]
n2[2-27]
n3[4-31]
n4[8-34]
n5[10-36]
n6[14-37]
*/
	 N1_L = 1,
	 N1_H = 21,
	
	 N2_L = 2,
	 N2_H = 27,
	
	 N3_L = 4,
	 N3_H = 31,
	
	 N4_L = 8,
	 N4_H = 34,
	
	 N5_L = 10,
	 N5_H = 36,
	
	 N6_L = 14,
	 N6_H = 37,

};




bool check_6(const char txt[]);
bool zugi_check_5(const char txt[]);

//void print_list(struct Toc *&head, int &printed,ofstream &tfo);
//--------------------------- FUNCTION 1---------------------------------------
void f1(struct Toc *&head);
void f2(int low,struct Toc *&head);
void f3(int low,struct Toc *&head);
void f4(int low,struct Toc *&head);
void f5(int low,struct Toc *&head);
void f6(int low,struct Toc *&head);
bool check_5(const char txt[]);

//------------------ WRITE ITEM CHAR[] TO FILE --------------------------------
void WriteToFile(ofstream &tfo,const char txt[]);
//void print_list(const struct Toc *head, int &printed, ofstream &tfo)
void print_list(const struct Toc *head, ofstream &tfo);
void menu(	struct Toc *&rosh,struct Toc *&results, int &clist);
void cinch(char *data);
void get_chanse(const struct Toc *head, char result[]);
void get_result_game_input(char result[]);
void get_result_game_file_input(ifstream &tfi ,char result[]);
void print_set_res(const struct Toc *head);
void set_res(struct Toc *head,const char res[]);


//------------------------ MAIN -----------------------------------------------
int main()
{
	//clock_t start = clock();					// set start time

	struct Toc *rosh = NULL;					// first pointer
	struct Toc *results = NULL;					// next pointer

	int clist;

		//asm("movl %ecx, %eax"); /* moves the contents of ecx to eax */

	//rosh = alloc_new();							// create head
 	rosh = results = alloc_new();						// create next in head
	//rosh->_next = results;						// set this head->_next to 
												// point to next struct
	
	menu(rosh,results,clist);			

	clear_memory(rosh);							// clear used memory
	
	//cout	 << "Time: " <<  (float(clock() - start) / CLOCKS_PER_SEC) << "\n";
	return(0);
}

void cinch(char *data)
{
	cin >> setw(MAX_STR_LEN) >> data;
}

void menu(struct Toc *&rosh,struct Toc *&results, int &clist)
{
	char comand[MAX_STR_LEN];
	char result[7];
	
	//char nis;
	//int ni;
	
	//cout << sizeof(nis) << " " << sizeof(ni) << "\n";
	cout 	<< "##################\tMenu:\t##################\n"
			<< "1.	Build results		:\t br\n"
			<< "2.	Number of combin	:\t sc\n"
			<< "3.	Write res to file	:\t wr - / wr filename\n"
			<< "4.	Get chanse		:\t gc\n"
			<< "5.	Get for file		:\t gcf\n"
			<< "6.	Build all		:\t ba\n"
			<< "9.	End and exit		:\t end / q\n\n";
	
	cinch(comand);
	
	
	if(!strcmp(comand,"br")|| !strcmp(comand,"1"))
	{
		f1(results);								// think all results
		
	}
	else if(!strcmp(comand,"sc") || !strcmp(comand,"2"))
	{
		clist =  counted(rosh->_next);				// cout all combinations
		cout << "Calculated: " << clist << "\n" ;	// print countes res
	}
	else if(!strcmp(comand,"wr") || !strcmp(comand,"3"))
	{
		ofstream file_output;                   	// set out stream file

		cinch(comand);		
		
		if(strcmp(comand,"-"))
			file_output.open(comand, ofstream::out);   // open file to write
		else
			file_output.open("output.txt", ofstream::out);   // open file to write

		if(!file_output.is_open())
			cout << "ERROR OUPUT FILE\n";
		else		
			print_list(rosh->_next ,file_output);		// write/print list into file

		
		file_output.close();						// clode output file
	
	}
	else if(!strcmp(comand,"gc") || !strcmp(comand,"4"))
	{
		
		get_result_game_input(result);
		get_chanse(rosh->_next,result);
	}
	else if(!strcmp(comand,"gcf") || !strcmp(comand,"5"))
	{
		
		ifstream    tfi;                        // prototype for reading files
		tfi.open("gr.loto");
		int counter_ofres = 0;
		if(tfi.is_open())
			while(tfi)	
			{
				counter_ofres++;
				cout << " \t# : - " << counter_ofres << "\n";
				get_result_game_file_input(tfi,result);
				print_item(result);
				get_chanse(rosh->_next,result);
			}
		
		tfi.close();        // close reasd file
	
	}	
	else if(!strcmp(comand,"ba") || !strcmp(comand,"6"))
	{
	
		ifstream    tfi;                        // prototype for reading files
		tfi.open("gr.loto");
		//int counter_ofres = 0;
		if(tfi.is_open())
		{
			while(tfi)	
			{
				get_result_game_file_input(tfi,result);
				set_res(rosh->_next,result);
			}
			
			tfi.close();        // close reasd file
			print_set_res(rosh->_next);
		}
	}
	else if(!strcmp(comand,"cm") || !strcmp(comand,"7"))
		clear_memory(rosh->_next->_next);
	else if(!strcmp(comand,"end") || !strcmp(comand,"q") || !strcmp(comand,"9"))
		return;
	
	cout << "Done.\n";
	menu(rosh,results,clist);

}


void print_set_res(const struct Toc *head)
{
	const struct Toc *temp;
	
	temp = head;
	while(temp != NULL )
	{
		if(temp->_ball > 50 && (temp->_ress[4] > 2 || temp->_ress[5] > 0 || temp->_ress[6] > 0))
		//if()
		{
			cout	<< temp->_ball << " << 3x" 
				 	<< temp->_ress[3-3] << " : 4x" << temp->_ress[4-3] << " : 5x" 
					<< temp->_ress[5-3] << " : 6x" << temp->_ress[6-3] << "\n";
			print_item(temp->_num);
		}	
		temp = temp->_next;
	}
	
}
void set_res(struct Toc *head,const char res[])
{
	struct Toc *temp;
	int pred = 0;
	
	temp	=	head;
	
	while(temp != NULL)
	{
		pred = predict_compare(temp->_num,res);
		
		
		if(pred>=3 && pred <=6)
		{
			temp->_ress[pred-3]++;
			temp->_ball += 10*(pred-3);
		}
			
		
		temp = temp->_next;
	}

}

//--------------------------- FUNCTION		6	-------------------------------
// 6666666666666666666666666666666666666666666666666666666666666666666666666666
void f6(int low,struct Toc *&head)
{
	int set = 0;
	char temp[7] ;
	//int pred_res = 0;
	
	if(low <= N6_L)
		set = N6_L;
	else
		set = low;
	
	for(int i=set;i<=N6_H;i++)
	{
		head->_num[5] = i - '\0';
		
		if(check_6(head->_num))
		//if(zugi_check_5(head->_num))
		{
			strcpy(temp,head->_num);
			head->_next = alloc_new();
			head = head->_next;
			strcpy(head->_num, temp);
		}
	}
}




void get_result_game_file_input(ifstream &tfi ,char result[])
{
	int res;
	//cout << "Enter numbers:\n";
	tfi >> res;
	result[0] = int2ch(res);
	tfi >> res;
	result[1] = int2ch(res);
	tfi >> res;
	result[2] = int2ch(res);
	tfi >> res;
	result[3] = int2ch(res);
	tfi >> res;
	result[4] = int2ch(res);
	tfi >> res;
	result[5] = int2ch(res);
}
void get_result_game_input(char result[])
{
	int res;
	cout << "Enter numbers:\n";
	cin >> res;
	result[0] = int2ch(res);
	cin >> res;
	result[1] = int2ch(res);
	cin >> res;
	result[2] = int2ch(res);
	cin >> res;
	result[3] = int2ch(res);
	cin >> res;
	result[4] = int2ch(res);
	cin >> res;
	result[5] = int2ch(res);
}

void get_chanse(const struct Toc *head ,char result[])
{
	const struct Toc *temp	=	NULL;
	
	

	int counter = 0;

	int pred_res = 0;
	unsigned mon_need = 0;
	int predicts[7];
	

	temp = head;
	predicts[0] = predicts[1] = predicts[2] = predicts[3]= predicts[4]=predicts[5]=predicts[6] = 0;
	while(temp != NULL)
	{
		//cout << redict_compare()
		pred_res = predict_compare(temp->_num,result);
		predicts[pred_res]++;
		
		temp = temp->_next;
		counter++;
	}
	mon_need = (unsigned)(counter*2.8);
	
	
	float tr = 0;
	float ch = 0;
	float pa = 0;
	float sh = 0;
	
	
	tr = predicts[3] * 10.01;
	ch = predicts[4] * 50.01;
	pa = predicts[5] * 500;
	sh = predicts[6] * 500000;
	
	int sum_win = (int)(tr + ch + pa + sh);
	
	cout << "All summe: " << mon_need << "\t" << "Sume win: " << sum_win 
			<< "\t Money gets: " << (int)(sum_win - mon_need) << "\n";
	
	cout << "Zero :" << predicts[0]	<< " : 1:" <<predicts[1] << " : 2:" <<predicts[2]
			<< " : 3:" <<predicts[3] << " : 4:" <<predicts[4]
			<< " : 5:" <<predicts[5] << " : 6:" <<predicts[6] << "\n";
}





//--------------------------- FUNCTION		5	-------------------------------
// 5555555555555555555555555555555555555555555555555555555555555555555555555555
void f5(int low,struct Toc *&head)
{
	int set = max(low,(int)N5_L);
	
	for(int i=set;i<=N5_H;i++)
	{
		head->_num[4] = i - '\0';
		//if(check_5(head->_num))
		f6(i+1,head);
	}
}



bool zugi_check(const int x1,const int x2,const int x3,
				const int x4,const int x5,const int x6)
{
	
	for(int i=2;i<=7;i++)
		if((x1%i == 0 && x2%i == 0 && x3%i == 0 && x4%i == 0 && x5%i == 0 && x6%i == 0)
		|| (x1%i != 0 && x2%i != 0 && x3%i != 0 && x4%i != 0 && x5%i != 0 && x6%i != 0))
			return(false);

	return(true);
}

bool check_6(const char txt[])
{
	int x1 = toint(txt[0]);
	int x2 = toint(txt[1]);
	int x3 = toint(txt[2]);
	int x4 = toint(txt[3]);
	int x5 = toint(txt[4]);
	int x6 = toint(txt[5]);

	if(!zugi_check(x1,x2,x3,x4,x5,x6))
		return(false);
	
	return(true);
}

bool zugi_check_5(const char txt[])
{
		
	int eq_count = 0;
	int eq_ncount = 0;
	
	for(int i=2;i<=7;i++)
	{
		eq_count = 0;
		eq_ncount = 0;
		
		for(int a=0;a<6;a++)
		{
			if((txt[a]-'\0')%i == 0)
				eq_count++;
			if((txt[a]-'\0')%i != 0)
				eq_ncount++;
				
			if(eq_count > 4 || eq_ncount > 5)	//	check equal
				return(false);	
		}	
	}
	
	return(true);

}
bool check_5(const char txt[])
{
	if(zugi_check_5(txt))
		return(true);
		
	return(false);
}


//void print_list(const struct Toc *head, int &printed, ofstream &tfo)
void print_list(const struct Toc *head, ofstream &tfo)
{
	const struct Toc *temp;
	
	temp = head;
	
	while(head != NULL)
	{
		WriteToFile(tfo,head->_num);
		head = head->_next;
	}

}

//--------------------------- FUNCTION 1---------------------------------------
void f1(struct Toc *&head)
{
	for(int i=N1_L;i<=N1_H;i++)
	{
		if(i%3==0)
			cout << "\t-\t-\t-" << (100*i)/(int)N1_H << "%\n";
		head->_num[0] = i - '\0';
		f2(i+1,head);
	}

}

void f2(int low,struct Toc *&head)
{
	int set = max(low,(int)N2_L);
		
	for(int i=set;i<=N2_H;i++)
	{
		head->_num[1] = i - '\0';
		f3(i+1,head);
	}
}

void f3(int low,struct Toc *&head)
{
	int set = max(low,(int)N3_L);
		
	for(int i=set;i<=N3_H;i++)
	{
		head->_num[2] = i - '\0';
		f4(i+1,head);
	}
}

void f4(int low,struct Toc *&head)
{
	int set = max(low,(int)N4_L);
			
	for(int i=set;i<=N4_H;i++)
	{
		head->_num[3] = i - '\0';
		f5(i+1,head);
	}
}





//------------------ WRITE ITEM CHAR[] TO FILE --------------------------------
void WriteToFile(ofstream &tfo,const char txt[])
{
	for(int i=0;i<6;i++)
		tfo << (int)(txt[i] - '\0') << " ";

	tfo << "\n";

}


